(import
  (except (rnrs base) let-values map error)
  (only (guile) lambda* λ command-line string-null?)
  (srfi srfi-1)
  (fileio))


(define concat-lines
  (lambda* (lines #:key (separator-test string-null?))
    (let next-line ([remaining-lines lines] [combined-line ""])
      (cond
       [(null? remaining-lines)
        (list (string-trim-both combined-line))]
       [else
        (let ([cur-line (first remaining-lines)])
          (cond
           ;; The passport-separator finishes an entry in
           ;; the lines. We cons the single passport data
           ;; onto the recursion and start collecting data
           ;; for the next single passport.
           [(separator-test cur-line)
            (cons (string-trim-both combined-line)
                  (next-line (cdr remaining-lines) ""))]
           ;; If more data for a single passport follows, we
           ;; append it onto the single passport data and
           ;; look at the next line.
           [else
            (next-line (cdr remaining-lines)
                       (string-append combined-line cur-line))]))]))))


(define unique-chars
  (λ (str)
    (define look-at-next-char
      (λ (remaining-chars previous-char unique-chars)
        (cond
         [(null? remaining-chars)
          unique-chars]
         [(char=? previous-char (first remaining-chars))
          (look-at-next-char (cdr remaining-chars)
                             previous-char
                             unique-chars)]
         [else
          (look-at-next-char (cdr remaining-chars)
                             (first remaining-chars)
                             (cons (first remaining-chars) unique-chars))])))

    (let ([sorted-chars (sort (string->list str) char<?)])
      (look-at-next-char (cdr sorted-chars)
                         (first sorted-chars)
                         (list (first sorted-chars))))))


(define main
  (λ (cmd-line-args)
    (let* ([lines (concat-lines (get-lines-from-file (second cmd-line-args)))])
      (apply + (map length (map unique-chars lines))))))


(simple-format (current-output-port)
               "~a\n"
               (main (command-line)))
